{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "from pyalink.alink import *\n",
    "useLocalEnv(1)\n",
    "\n",
    "from utils import *\n",
    "import os\n",
    "import pandas as pd\n",
    "\n",
    "DATA_DIR = ROOT_DIR + \"mushroom\" + os.sep\n",
    "\n",
    "ORIGIN_FILE = \"agaricus-lepiota.data\"\n",
    "TRAIN_FILE = \"train.ak\"\n",
    "TEST_FILE = \"test.ak\"\n",
    "\n",
    "COL_NAMES = [\n",
    "    \"class\",\n",
    "    \"cap_shape\", \"cap_surface\", \"cap_color\", \"bruises\", \"odor\",\n",
    "    \"gill_attachment\", \"gill_spacing\", \"gill_size\", \"gill_color\",\n",
    "    \"stalk_shape\", \"stalk_root\", \"stalk_surface_above_ring\", \"stalk_surface_below_ring\",\n",
    "    \"stalk_color_above_ring\", \"stalk_color_below_ring\",\n",
    "    \"veil_type\", \"veil_color\",\n",
    "    \"ring_number\", \"ring_type\", \"spore_print_color\", \"population\", \"habitat\"    \n",
    "]\n",
    "\n",
    "COL_TYPES = [\n",
    "    \"string\",\n",
    "    \"string\", \"string\", \"string\", \"string\", \"string\",\n",
    "    \"string\", \"string\", \"string\", \"string\", \"string\",\n",
    "    \"string\", \"string\", \"string\", \"string\", \"string\",\n",
    "    \"string\", \"string\", \"string\", \"string\", \"string\",\n",
    "    \"string\", \"string\"\n",
    "]\n",
    "\n",
    "LABEL_COL_NAME = \"class\"\n",
    "\n",
    "FEATURE_COL_NAMES = COL_NAMES.copy()\n",
    "FEATURE_COL_NAMES.remove(LABEL_COL_NAME)\n",
    "\n",
    "PREDICTION_COL_NAME = \"pred\"\n",
    "PRED_DETAIL_COL_NAME = \"predInfo\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#c_1\n",
    "source = CsvSourceBatchOp()\\\n",
    "    .setFilePath(DATA_DIR + ORIGIN_FILE)\\\n",
    "    .setSchemaStr(generateSchemaString(COL_NAMES, COL_TYPES))\n",
    "\n",
    "source.lazyPrint(5, \"< origin data >\")\n",
    "\n",
    "splitTrainTestIfNotExist(source, DATA_DIR + TRAIN_FILE, DATA_DIR + TEST_FILE, 0.9)\n",
    "\n",
    "AkSourceBatchOp()\\\n",
    "    .setFilePath(DATA_DIR + TRAIN_FILE)\\\n",
    "    .link(\n",
    "        ChiSqSelectorBatchOp()\\\n",
    "            .setSelectorType(\"NumTopFeatures\")\\\n",
    "            .setNumTopFeatures(3)\\\n",
    "            .setSelectedCols(FEATURE_COL_NAMES)\\\n",
    "            .setLabelCol(LABEL_COL_NAME)\\\n",
    "            .lazyPrintModelInfo(\"< Chi-Square Selector >\")\n",
    "    )\n",
    "\n",
    "AkSourceBatchOp()\\\n",
    "    .setFilePath(DATA_DIR + TRAIN_FILE)\\\n",
    "    .select(\"veil_type\")\\\n",
    "    .distinct()\\\n",
    "    .lazyPrint(100)\n",
    "\n",
    "BatchOperator.execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#c_2_1\n",
    "train_data = AkSourceBatchOp().setFilePath(DATA_DIR + TRAIN_FILE);\n",
    "test_data = AkSourceBatchOp().setFilePath(DATA_DIR + TEST_FILE);\n",
    "\n",
    "trainer = NaiveBayesTrainBatchOp()\\\n",
    "    .setFeatureCols(FEATURE_COL_NAMES)\\\n",
    "    .setCategoricalCols(FEATURE_COL_NAMES)\\\n",
    "    .setLabelCol(LABEL_COL_NAME)\n",
    "\n",
    "predictor = NaiveBayesPredictBatchOp()\\\n",
    "    .setPredictionCol(PREDICTION_COL_NAME)\\\n",
    "    .setPredictionDetailCol(PRED_DETAIL_COL_NAME)\n",
    "\n",
    "train_data.link(trainer);\n",
    "predictor.linkFrom(trainer, test_data);\n",
    "\n",
    "trainer.lazyPrintModelInfo();\n",
    "\n",
    "def print_model_info(naiveBayesModelInfo: NaiveBayesModelInfo):\n",
    "    for feature in [\"odor\", \"spore_print_color\", \"gill_color\"]:\n",
    "        print(\"feature: \" + feature)\n",
    "        print(naiveBayesModelInfo.getCategoryFeatureInfo().get(feature))\n",
    "\n",
    "trainer.lazyCollectModelInfo(print_model_info)\n",
    "\n",
    "predictor.lazyPrint(10, \"< Prediction >\");\n",
    "\n",
    "predictor\\\n",
    "    .link(\n",
    "        EvalBinaryClassBatchOp()\\\n",
    "            .setPositiveLabelValueString(\"p\")\\\n",
    "            .setLabelCol(LABEL_COL_NAME)\\\n",
    "            .setPredictionDetailCol(PRED_DETAIL_COL_NAME)\\\n",
    "            .lazyPrintMetrics()\n",
    "    )\n",
    "\n",
    "BatchOperator.execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#c_2_2\n",
    "train_data = AkSourceBatchOp().setFilePath(DATA_DIR + TRAIN_FILE)\n",
    "test_data = AkSourceBatchOp().setFilePath(DATA_DIR + TEST_FILE)\n",
    "\n",
    "trainer = NaiveBayesTrainBatchOp()\\\n",
    "    .setFeatureCols([\"odor\", \"gill_color\"])\\\n",
    "    .setCategoricalCols([\"odor\", \"gill_color\"])\\\n",
    "    .setLabelCol(LABEL_COL_NAME);\n",
    "\n",
    "predictor = NaiveBayesPredictBatchOp()\\\n",
    "    .setPredictionCol(PREDICTION_COL_NAME)\\\n",
    "    .setPredictionDetailCol(PRED_DETAIL_COL_NAME);\n",
    "\n",
    "train_data.link(trainer);\n",
    "predictor.linkFrom(trainer, test_data);\n",
    "\n",
    "def print_model_info(naiveBayesModelInfo: NaiveBayesModelInfo):\n",
    "    for feature in [\"odor\", \"gill_color\"]:\n",
    "        print(\"feature: \" + feature)\n",
    "        print(naiveBayesModelInfo.getCategoryFeatureInfo().get(feature))\n",
    "\n",
    "trainer.lazyCollectModelInfo(print_model_info);\n",
    "\n",
    "predictor\\\n",
    "    .lazyPrint(10, \"< Prediction >\")\\\n",
    "    .link(\n",
    "        EvalBinaryClassBatchOp()\\\n",
    "            .setPositiveLabelValueString(\"p\")\\\n",
    "            .setLabelCol(LABEL_COL_NAME)\\\n",
    "            .setPredictionDetailCol(PRED_DETAIL_COL_NAME)\\\n",
    "            .lazyPrintMetrics()\n",
    "    );\n",
    "\n",
    "BatchOperator.execute();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#c_3_1\n",
    "df = pd.DataFrame(\n",
    "    [\n",
    "        [\"sunny\", 85.0, 85.0, False, \"no\"],\n",
    "        [\"sunny\", 80.0, 90.0, True, \"no\"],\n",
    "        [\"overcast\", 83.0, 78.0, False, \"yes\"],\n",
    "        [\"rainy\", 70.0, 96.0, False, \"yes\"],\n",
    "        [\"rainy\", 68.0, 80.0, False, \"yes\"],\n",
    "        [\"rainy\", 65.0, 70.0, True, \"no\"],\n",
    "        [\"overcast\", 64.0, 65.0, True, \"yes\"],\n",
    "        [\"sunny\", 72.0, 95.0, False, \"no\"],\n",
    "        [\"sunny\", 69.0, 70.0, False, \"yes\"],\n",
    "        [\"rainy\", 75.0, 80.0, False, \"yes\"],\n",
    "        [\"sunny\", 75.0, 70.0, True, \"yes\"],\n",
    "        [\"overcast\", 72.0, 90.0, True, \"yes\"],\n",
    "        [\"overcast\", 81.0, 75.0, False, \"yes\"],\n",
    "        [\"rainy\", 71.0, 80.0, True, \"no\"]\n",
    "    ]\n",
    ")\n",
    "\n",
    "source = BatchOperator.fromDataframe(df, schemaStr=\"Outlook string, Temperature double, Humidity double, Windy boolean, Play string\")\n",
    " \n",
    "source.lazyPrint(-1);\n",
    "\n",
    "source\\\n",
    "    .link(\n",
    "        C45TrainBatchOp()\\\n",
    "            .setFeatureCols([\"Outlook\", \"Temperature\", \"Humidity\", \"Windy\"])\\\n",
    "            .setCategoricalCols([\"Outlook\", \"Windy\"])\\\n",
    "            .setLabelCol(\"Play\")\\\n",
    "            .lazyPrintModelInfo()\\\n",
    "            .lazyCollectModelInfo(\n",
    "                lambda decisionTreeModelInfo: \n",
    "                    decisionTreeModelInfo.saveTreeAsImage(\n",
    "                        DATA_DIR + \"weather_tree_model.png\", True)\n",
    "        )\n",
    "    );\n",
    "\n",
    "BatchOperator.execute();"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "#c_3_2\n",
    "train_data = AkSourceBatchOp().setFilePath(DATA_DIR + TRAIN_FILE);\n",
    "test_data = AkSourceBatchOp().setFilePath(DATA_DIR + TEST_FILE);\n",
    "\n",
    "for treeType in ['GINI', 'INFOGAIN', 'INFOGAINRATIO'] :\n",
    "    model = train_data.link(\n",
    "        DecisionTreeTrainBatchOp()\\\n",
    "            .setTreeType(treeType)\\\n",
    "            .setFeatureCols(FEATURE_COL_NAMES)\\\n",
    "            .setCategoricalCols(FEATURE_COL_NAMES)\\\n",
    "            .setLabelCol(LABEL_COL_NAME)\\\n",
    "            .lazyPrintModelInfo(\"< \" + treeType + \" >\")\\\n",
    "            .lazyCollectModelInfo(\n",
    "                lambda decisionTreeModelInfo:\n",
    "                    decisionTreeModelInfo.saveTreeAsImage(\n",
    "                        DATA_DIR + \"tree_\" + treeType + \".jpg\", True)\n",
    "            )\n",
    "    );\n",
    "\n",
    "    predictor = DecisionTreePredictBatchOp()\\\n",
    "        .setPredictionCol(PREDICTION_COL_NAME)\\\n",
    "        .setPredictionDetailCol(PRED_DETAIL_COL_NAME);\n",
    "\n",
    "    predictor.linkFrom(model, test_data);\n",
    "\n",
    "    predictor.link(\n",
    "        EvalBinaryClassBatchOp()\\\n",
    "            .setPositiveLabelValueString(\"p\")\\\n",
    "            .setLabelCol(LABEL_COL_NAME)\\\n",
    "            .setPredictionDetailCol(PRED_DETAIL_COL_NAME)\\\n",
    "            .lazyPrintMetrics(\"< \" + treeType + \" >\")\n",
    "    )\n",
    "\n",
    "BatchOperator.execute()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.8.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
